using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace ADiKt {
    /// <summary>
    /// the main game screen
    /// </summary>
    /// 
    class GameplayScreen : Screen {
        ContentManager content;
        RoundLineManager lineBatch;
        int liveWorms;
        float pauseAlpha;
        TimeSpan startTime;
        Texture2D startArrow;


        public GameplayScreen() {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
            gameReset();
        }

        ///<summary> resets the screen, and prepare for the next round </summary>
        //Todo - initial flash and arrows
        public void roundReset() {
            //ScreenManager.Game.ResetElapsedTime();
            Globals.points = new List<RoundLine>[Globals.gridSize, Globals.gridSize];
            for (int x = 0; x < Globals.gridSize; x++) {
                for (int y = 0; y < Globals.gridSize; y++) {
                    Globals.points[x, y] = new List<RoundLine>();
                }
            }
            foreach (Worm w in Globals.worms) { w.reset(); }
            startTime = TimeSpan.FromSeconds(1);
        }

        ///<summary> resets the score and prepares for a new game </summary>
        public void gameReset() {
            foreach (Worm w in Globals.worms) {
                w.score = 0f;
            }
            roundReset();
        }

        /// <summary> loads the relevant content into the shared content manager </summary>
        public override void LoadContent() {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");
            lineBatch = new RoundLineManager(ScreenManager.GraphicsDevice, content);
            ScreenManager.Game.ResetElapsedTime();
            startArrow = content.Load<Texture2D>("arrow");
        }

        /// <summary> unloads all content for this screen, relesing the memory </summary>
        public override void UnloadContent() {
            content.Unload();
        }

        /// <summary> contains the main game logic, called every frame, and handels pausing </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) {
            base.Update(gameTime, otherScreenHasFocus, false);

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1.5f);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);

            //update worms and handel global game states
            if (IsActive){
                liveWorms = 0;
                foreach (Worm w in Globals.worms) {
                    if (w.alive) {
                        w.update(Keyboard.GetState());
                        liveWorms += 1;
                    }
                }
                if (liveWorms == 1) {
                    foreach (Worm w in Globals.worms) {
                        if (w.alive) {
                            w.score += 25;
                        }
                    }
                    roundReset();
                }
            }
        }

        /// <summary> handles all universal game input e.g. pausing  </summary>
        public override void HandleInput(InputState input) {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;
            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];

            if (input.IsPauseGame(ControllingPlayer)) {
                ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            } 
        }

        /// <summary> draws the HUD (score and round) ans the lines to the screen </summary>
        public override void Draw(GameTime gameTime) {
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target, Color.Black, 0, 0);
            SpriteBatch spriteBatch = this.ScreenManager.SpriteBatch;
            SpriteFont font = this.ScreenManager.smallFont;

            foreach (Worm w in Globals.worms) { lineBatch.Draw(w.bodyLines, 2f, w.colour, Globals.viewProjMatrix); }

            spriteBatch.Begin();
            //draws the scorebord
            Vector2 position = new Vector2(0f,0f);
            string text;
            //Todo - fix flickering
            Globals.worms.Sort(delegate(Worm p1, Worm p2) { return p1.score.CompareTo(p2.score); });
            
            foreach (Worm w in Globals.worms) {
                text = Globals.colListUsed[w.colour] + ": " + Math.Round(w.score).ToString(); 
                spriteBatch.DrawString(font, text, position, w.colour, 0, Vector2.Zero, 1, SpriteEffects.None, 0);
                position.Y += 20f;
            }
            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0) {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);
                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }
    }
}